package repository

import (
	"context"
	"github.com/aphasia51/website/internal/domain"
	"github.com/aphasia51/website/internal/repository/dao"
	"github.com/jinzhu/copier"
)

type AccidentRepository struct {
	dao *dao.AccidentDAO
}

func NewAccidentRepository(dao *dao.AccidentDAO) *AccidentRepository {
	return &AccidentRepository{
		dao: dao,
	}
}

func (r *AccidentRepository) Create(ctx context.Context, a domain.Accident) (int64, error) {
	rows, err := r.dao.Create(ctx, dao.Accident{
		Title:         a.Title,
		TitleEn:       a.TitleEn,
		Year:          a.Year,
		Location:      a.Location,
		Dead:          a.Dead,
		Injure:        a.Injure,
		Degree:        a.Degree,
		Season:        a.Season,
		Chemicals:     a.Chemicals,
		Equipments:    a.Equipments,
		Consumables:   a.Consumables,
		Description:   a.Description,
		DescriptionEn: a.DescriptionEn,
	})

	if err != nil {
		return 0, err
	}

	return rows, nil
}

func (r *AccidentRepository) Query(ctx context.Context, a domain.AccidentSearchParam) ([]domain.Accident, error) {
	accidents, err := r.dao.Query(ctx, dao.AccidentSearchParam{
		Title:        a.Title,
		ChemicalId:   a.ChemicalId,
		EquipmentId:  a.EquipmentId,
		ConsumableId: a.ConsumableId,
		Season:       a.Season,
	})

	if err != nil {
		return []domain.Accident{}, err
	}

	returnValue := make([]domain.Accident, 0)
	for _, v := range accidents {
		returnValue = append(returnValue, domain.Accident{
			Id:            v.Id,
			Title:         v.Title,
			TitleEn:       v.TitleEn,
			Year:          v.Year,
			Location:      v.Location,
			Dead:          v.Dead,
			Injure:        v.Injure,
			Degree:        v.Degree,
			Season:        v.Season,
			Description:   v.Description,
			DescriptionEn: v.DescriptionEn,
		})
	}

	return returnValue, nil
}

func (r *AccidentRepository) Delete(ctx context.Context, ids []string) (int64, error) {
	affectedRows, err := r.dao.Delete(ctx, ids)

	if int64(len(ids)) != affectedRows {
		return 0, err
	}

	return affectedRows, nil
}

func (r *AccidentRepository) QueryRelatedItem(ctx context.Context, id string) (domain.AccidentItems, error) {
	items, err := r.dao.QueryRelatedItem(ctx, id)

	if err != nil {
		panic(err)
	}

	returnValue := domain.AccidentItems{}
	returnValue.Chemicals = items.Chemicals
	returnValue.Equipments = items.Equipments
	returnValue.Consumables = items.Consumables

	return returnValue, nil
}

func (r *AccidentRepository) UpdateRelatedItem(ctx context.Context, accidentId string, itemType string, items []string) (int64, error) {
	effectedRows, err := r.dao.UpdateRelatedItem(ctx, accidentId, itemType, items)

	if err != nil {
		panic(err)
	}

	return effectedRows, nil
}

func (r *AccidentRepository) QueryItemAll(ctx context.Context, accident_id string, item_type string) ([]domain.TreeItem, error) {
	treeItem, err := r.dao.QueryItemAll(ctx, accident_id, item_type)

	var returnValue []domain.TreeItem
	err = copier.Copy(&returnValue, treeItem)
	if err != nil {
		return []domain.TreeItem{}, err
	}

	return returnValue, nil
}
